/******************************************************************************
*
* This file is part of FreeTrack (http://code.google.com/p/qtfreetrack).
* BY Willy Gardiol (willy@gardiol.org)
*
* FreeTrack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeTrack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar.  If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/

#ifndef LAYERTRACK_H
#define LAYERTRACK_H

#include "layer.h"
#include "trackwaypoint.h"
#include "trackpoint.h"

#define TRACK_MIN_SIZE 3
#define TRACK_MAX_SIZE 10

class FreeTrackWidget;
class WorkerLoadGpx;
class WorkerAutoLoad;

class LayerTrack : public Layer
{
    Q_OBJECT
public:
    explicit LayerTrack(bool);
    ~LayerTrack();

    // Reset track to empty
    void resetTrack();

    // Paint the track on the table
    void paintLayer(QPainter&, const QTransform&, const QRectF&);

    // am i a live track?
    bool isLiveTrack();

    friend class WorkerLoadGpx;
    friend class WorkerAutoLoad;

public: // Manage filename
    // get/check filename
    QString getFilename();
    // return filename for the extra data
    QString getExtraFilename();
    // is the filename set?
    bool isFilenameSet();

    // This flag is used to prevent any overwriting of the GPX file if this is NOT a live track.
    // TODO: this is so ugly... I really really NEED to make a derived class: LayerTrackLive!
    bool is_live_track;

    // Load track (both GPX and extra data)
    bool loadTrack( QString filename );
    // Save track (both GPX and extra data)
    void saveTrack( bool save_as = false );
    // Save extra-data (color, size...)
    bool saveExtra();

public: // waypoint management
    // Add a new waypoint from a TrackPoint
    void addWaypoint( const TrackPoint&, const QString&, const QString& );
    // Remove a waypoint
    bool removeWaypoint( int );
    // Get all waypoint IDs
    QList<int> listWaypointIDs();
    // Get a waypoint given specific ID
    TrackWaypoint getWaypoint(int wid, QString& n, QString& d );
    // Update a waypoint with new title & description
    bool updateWaypoint(int,const QString,const QString);

public: // Data management
    // Export a track to GPX format (and zip it if requested)
    bool toXml(QByteArray*);

    // Manage track color
    QColor getColor();
    void setColor( QColor );
    // Manager track size
    int getSize();
    void setSize(int);

    // Return number of trackpoints
    int countTrackPoints();
    // return length of track, in kms
    qreal getTrackLength();

    // Return last live track point
    TrackPoint getLastPoint();

    // Convert any existing quicksave stale files
    void processQuickSave();


public: // Layer specific methods
    // Return a widget used to configure the layer. The caller must display the widget.
    FreeTrackWidget* getConfigureLayer();
    // Return a widget used to display the layer in the layer manager
    FreeTrackWidget* getLayerLabel();

signals:
    // Notify of new point added to the track
    void newPointAdded();
    // Notify of track changes
    void trackChanged(int points = 0, qreal length = 0.0 );
    // Notify color and size change
    void colorChanged(QColor);
    void sizeChanged(int);

public slots:
    // Receive a new point (might not be added, tough)
    void addPoint(const TrackPoint&);
    // start/stop tracking
    void startTracking(bool);
    // activate/deactivate autosave feature
    void setAutosave(bool);
    // Save modifications on quit
    void prepareToQuit();

private: // track status
    // Autosave enabled
    bool autosave;
    // Tracking active
    bool tracking;

private: // Track data points and stuff
    // Length of track, in meters
    qreal length;
    // Keep track of last leg, in case we drop it, we can quickly update the length back
    qreal last_length;
    // List of trackpoints
    QList<TrackPoint> data;
    // Quick access list of points for drawing purposes only
    QList<QPointF> points;

    // Actually insert a point into the list
    void appendTrackPoint(const TrackPoint& );
    // Actually remove last point from the list
    void removeTrackPoint();
    // Empty the track (will not emit any signals)
    void emptyTrack();

private: // Waypoints...
    // List of waypoints
    WaypointsHash waypoints;
//    QHash<int, TrackWaypoint> waypoints;
    void appendWaypoint(TrackWaypoint&);

private: // other data
    // Filename of the track
    QString filename;
    // Filename for autosave
    QString quickFilename;
    // track boundary rect, to optimize drawing!
    QRectF bound_rect;
    // Is the rect initialized?
    int bound_rect_points;
    // Update boundary
    void expandBoundary( const QPointF& );

private: // Quick autosave management
    // write a quicksave file
    void quickSave(const TrackPoint*, const TrackWaypoint*);

private: // GPX management
    // Save GPX to disk
    bool saveGpx();
    // Load GPX
    bool loadGpx();

private: // extra data management
    // Load extra-data (color, size...)
    bool loadExtra();
    // Color and size
    QColor color;
    int size;

private: // Modifiy management
    // we need to track whether XML or extra-data is modified
    bool extra_modified;
    bool gpx_modified;
    // Manage this complex modified stuff
    void setModified( bool gpx, bool extra );

};

#endif // LAYERTRACK_H
